﻿using System;
#if TASKSUPPORT
using System.Threading.Tasks;
#endif
using System.Windows.Threading;

using MugenMvvmToolkit.Interfaces;

namespace MugenMvvmToolkitTest.TestInfrastructure
{
    public class TestThreadManager : IThreadManager
    {
        #region Properties

        public Action InvokeInUiAction { get; set; }

        public Action InvokeInUiSynchronousAction { get; set; }

        public Action<object> InvokeAsyncAction { get; set; }

        public object InvokeAsyncState { get; set; }

        public bool ImmediateInvokeInUiSynchronous { get; set; }

        public bool ImmediateInvokeInUi { get; set; }

        public bool ImmediateInvokeAsync { get; set; }

        #endregion

        #region Implementation of IThreadManager

        /// <summary>
        ///     Gets or sets a dispatcher associated with current UI thread.
        /// </summary>
        public Dispatcher UiDispatcher { get; set; }

#if WPF
        /// <summary>
        /// Gets or sets the priority of asynchronous operations.
        /// </summary>
        public DispatcherPriority AsynchronousPriority { get; set; }

        /// <summary>
        /// Gets or sets the priority of synchronous operations.
        /// </summary>
        public DispatcherPriority SynchronousPriority { get; set; }

        /// <summary>
        ///     Invokes an action on the UI thread using the UiDispatcher.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="System.Action" />.
        /// </param>
        /// <param name="priority">The specified <see cref="System.Windows.Threading.DispatcherPriority"/> to invoke the action.</param>
        void IThreadManager.InvokeInUi(Action action, DispatcherPriority priority)
        {
            ((IThreadManager)this).InvokeInUi(action);
        }

        /// <summary>
        ///     Invokes an action on the UI thread synchronous using the UiDispatcher.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="System.Action" />.
        /// </param>
        /// <param name="priority">The specified <see cref="System.Windows.Threading.DispatcherPriority"/> to invoke the action.</param>
        void IThreadManager.InvokeInUiSynchronous(Action action, DispatcherPriority priority)
        {
            ((IThreadManager)this).InvokeInUiSynchronous(action);
        }        
#endif

        /// <summary>
        /// Determines whether the calling thread is the UI thread.
        /// </summary>        
        /// <returns><c>true</c> if the calling thread is the UI thread; otherwise, <c>false</c>.</returns>
        public bool IsUiThread { get; set; }

        /// <summary>
        ///     Invokes an action on the UI thread.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="System.Action" />.
        /// </param>
        void IThreadManager.InvokeInUi(Action action)
        {
            InvokeInUiAction = action;
            if (ImmediateInvokeInUi)
                action();
        }

        /// <summary>
        ///     Invokes an action on the UI thread synchronous.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="System.Action" />.
        /// </param>
        void IThreadManager.InvokeInUiSynchronous(Action action)
        {
            InvokeInUiSynchronousAction = action;
            if (ImmediateInvokeInUiSynchronous)
                action();
        }

        /// <summary>
        ///     Invokes an action asynchronous.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="System.Action" />.
        /// </param>
        /// <param name="state">The specified state.</param>
        void IThreadManager.InvokeAsync(Action<object> action, object state)
        {
            InvokeAsyncAction = action;
            InvokeAsyncState = state;
            if (ImmediateInvokeAsync)
                InvokeAsyncAction(state);
        }

#if TASKSUPPORT
        /// <summary>
        /// Gets or sets a <see cref="System.Threading.Tasks.TaskScheduler"/> associated with current UI thread.
        /// </summary>
        public TaskScheduler UiTaskScheduler { get; set; }

        /// <summary>
        /// Gets or sets a <see cref="System.Threading.Tasks.TaskScheduler"/> not associated with current UI thread.
        /// </summary>
        public TaskScheduler NonUiTaskScheduler { get; set; }
#endif
        #endregion
    }
}